package main

import (
	"context"
	"net/http"
)

type AuthPlugin struct {
	realm   string
	users   map[string]string
	enabled bool
}

func New() interface{} {
	return &AuthPlugin{
		users: make(map[string]string),
	}
}

func (p *AuthPlugin) Name() string {
	return "auth"
}

func (p *AuthPlugin) Version() string {
	return "1.0.0"
}

func (p *AuthPlugin) Init(ctx context.Context, config map[string]interface{}) error {
	if realm, ok := config["realm"].(string); ok {
		p.realm = realm
	}

	if users, ok := config["users"].(map[string]interface{}); ok {
		for username, password := range users {
			if pass, ok := password.(string); ok {
				p.users[username] = pass
			}
		}
	}

	if enabled, ok := config["enabled"].(bool); ok {
		p.enabled = enabled
	}

	return nil
}

func (p *AuthPlugin) Start() error {
	return nil
}

func (p *AuthPlugin) Stop() error {
	return nil
}

func (p *AuthPlugin) HandleRequest(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if !p.enabled {
			next.ServeHTTP(w, r)
			return
		}

		username, password, ok := r.BasicAuth()
		if !ok {
			w.Header().Set("WWW-Authenticate", `Basic realm="`+p.realm+`"`)
			http.Error(w, "Unauthorized", http.StatusUnauthorized)
			return
		}

		expectedPassword, exists := p.users[username]
		if !exists || password != expectedPassword {
			http.Error(w, "Unauthorized", http.StatusUnauthorized)
			return
		}

		next.ServeHTTP(w, r)
	})
}
